home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / mxcode / adnmod02 / gus.inc < prev    next >
Text File  |  1995-03-14  |  9KB  |  420 lines

  1. const
  2.   _active_voice = $102;
  3.   _command = $103;
  4.   _data_low = $104;
  5.   _data_high = $105;
  6.   _dram_io = $107;
  7.  
  8.   active_voice : word =  _active_voice;
  9.   command : word = _command;
  10.   data_low : word = _data_low;
  11.   data_high : word = _data_high;
  12.   dram_io : word = _dram_io;
  13.   gus_info : array[0..7] of byte = ($42,$45,$54,$41,$2f,$41,$44,$4e);
  14.  
  15. {$s-}
  16. Procedure GUSDelay; Assembler;
  17. ASM
  18.   mov   dx,base
  19.   add   dx,$100
  20.   in    al, dx
  21.   in    al, dx
  22.   in    al, dx
  23.   in    al, dx
  24.   in    al, dx
  25.   in    al, dx
  26.   in    al, dx
  27. End;
  28.  
  29. Function VoicePos( V : Byte) : Longint;
  30. Var
  31.   P : Longint;
  32.   I, Temp0, Temp1 : Word;
  33. Begin
  34.   Port [active_voice] := V;
  35.   Port [command] := $8A;
  36.   Temp0 := Portw[data_low];
  37.   Port [command] := $8B;
  38.   Temp1 := Portw[data_low];
  39.   VoicePos := (Temp0 SHL 7)+ (Temp1 SHR 8);
  40. End;
  41.  
  42.  
  43. Function  GUSPeek(Loc : Longint) : Byte;
  44. Var
  45.   B : Byte;
  46.   AddLo : Word;
  47.   AddHi : Byte;
  48. Begin
  49.   AddLo := Loc AND $FFFF;
  50.   AddHi := LongInt(Loc AND $FF0000) SHR 16;
  51.  
  52.   Port [base+$103] := $43;
  53.   Portw[base+$104] := AddLo;
  54.   Port [base+$103] := $44;
  55.   Port [base+$105] := AddHi;
  56.  
  57.   B := Port[base+$107];
  58.   GUSPeek := B;
  59. End;
  60.  
  61.  
  62. Procedure GUSPoke(Loc : Longint; B : Byte);
  63. Var
  64.   AddLo : Word;
  65.   AddHi : Byte;
  66. Begin
  67.   AddLo := Loc AND $FFFF;
  68.   AddHi := longint(Loc and $ff0000) shr 16;
  69.   Port [Base+$103] := $43;
  70.   Portw[Base+$104] := AddLo;
  71.   Port [Base+$103] := $44;
  72.   Port [Base+$105] := AddHi;
  73.   Port [Base+$107] := B;
  74. End;
  75.  
  76.  
  77. Function GUSProbe(adr : word) : Boolean;
  78. Var
  79.   B: Byte;
  80.   obase : word;
  81. Begin
  82.   obase := base;
  83.   base := adr;
  84.   Port [base+$103] := $4C;
  85.   Port [base+$105] := 0;
  86.   GUSDelay;
  87.   GUSDelay;
  88.   Port [base+$103] := $4C;
  89.   Port [base+$105] := 1;
  90.   GUSPoke(0, $AA);
  91.   GUSPoke($100, $55);
  92.   B := GUSPeek(0);
  93.   base := obase;
  94.   If B = $AA then GUSProbe := True else GUSProbe := False;
  95. End;
  96.  
  97.  
  98. Procedure GUSFind;
  99. Var
  100.   I : Word;
  101.   b : word;
  102. Begin
  103.   if base = $200 then begin
  104.     i := 1;
  105.     while i < 8 do begin
  106.       B := $200 + I*$10;
  107.       If GUSProbe(b) then I := 8;
  108.       inc(i);
  109.     End;
  110.     if b < $280 then base := b
  111.     else base := $200;
  112.   end;
  113.   if base <> $200 then begin
  114.     active_voice := base+_active_voice;
  115.     command := base+_command;
  116.     data_low := base+_data_low;
  117.     data_high := base+_data_high;
  118.     dram_io := base+_dram_io;
  119.   end;
  120. End;
  121.  
  122.  
  123. Function  GUSFindMem : Longint;
  124. { Returns how much RAM is available on the GUS }
  125. Var
  126.   I : Longint;
  127.   B : Byte;
  128. Begin
  129.   GUSPoke($40000, $AA);
  130.   If GUSPeek($40000) <> $AA then I := $3FFFF
  131.     else
  132.   Begin
  133.     GUSPoke($80000, $AA);
  134.     If GUSPeek($80000) <> $AA then I := $8FFFF
  135.       else
  136.     Begin
  137.       GUSPoke($C0000, $AA);
  138.       If GUSPeek($C0000) <> $AA then I := $CFFFF
  139.         else I := $FFFFF;
  140.     End;
  141.   End;
  142.   guspoke(0,$aa);
  143.   if guspeek(0) <> $aa then i := 0;
  144.   GUSFindMem := I;
  145. End;
  146.  
  147. Procedure GUSSetFreq( V : Byte; hz : Word); assembler;
  148. asm
  149.   cli
  150.   mov  dx,active_voice
  151.   mov  al,v
  152.   out  dx,al
  153.   mov  dx,command
  154.   mov  al,1
  155.   out  dx,al
  156.   mov  dx,data_low
  157.   mov  ax,hz
  158.   out  dx,ax
  159.  
  160.   {Port [Base+$102] := V;
  161.   Port [Base+$103] := 1;
  162.   Portw[Base+$104] := hz;}
  163.   sti
  164. end;
  165.  
  166. Procedure GUSVoiceControl( V, B : Byte);
  167. Begin
  168.   asm cli end;
  169.   Port [Base+$102] := V;
  170.   Port [Base+$102] := V;
  171.   Port [Base+$102] := V;
  172.   Port [Base+$103] := $0;
  173.   Port [Base+$105] := B;
  174.   asm sti end;
  175. End;
  176.  
  177. Procedure GUSSetBalance( V, Bal : Byte);
  178. Begin
  179.   asm cli
  180.  
  181.   mov  dx,active_voice
  182.   mov  al,v
  183.   out  dx,al
  184.   mov  dx,command
  185.   mov  al,0ch
  186.   out  dx,al
  187.   mov  dx,data_high
  188.   mov  al,bal
  189.   out  dx,al
  190.  
  191.   {Port [active_voice] := V;
  192.   Port [command] := $C;
  193.   Port [data_high] := Bal;}
  194.   sti
  195.   end;
  196. End;
  197.  
  198. Procedure GUSSetVolume( V : Byte; Vol : Word); assembler;
  199. asm
  200.   cli
  201.   mov  dx,active_voice
  202.   mov  al,v
  203.   out  dx,al
  204.   mov  dx,command
  205.   mov  al,9
  206.   out  dx,al
  207.   mov  dx,data_low
  208.   mov  ax,vol
  209.   out  dx,ax
  210.   {Port [Base+$102] := V;
  211.   Port [Base+$103] := 9;
  212.   Portw[Base+$104] := Vol;}  { 0-0ffffh, log ... not linear }
  213.   sti
  214. End;
  215.  
  216. Procedure GUSSetLoopMode( V : Byte);
  217. Var
  218.   Temp : Byte;
  219. Begin
  220.   asm cli end;
  221.   Port [Base+$102] := V;
  222.   Port [Base+$102] := V;
  223.   Port [Base+$102] := V;
  224.   Port [Base+$103] := $80;
  225.   Temp := Port[Base+$105];
  226.   Port [Base+$103] := 0;
  227.   Port [Base+$105] := (Temp AND $E7) OR 0;
  228.   asm sti end;
  229. End;
  230.  
  231. Procedure GUSStopVoice( V : Byte);
  232. Var
  233.   Temp : Byte;
  234. Begin
  235.   asm cli end;
  236.   Port [active_voice] := V;
  237.   Port [active_voice] := V;
  238.   Port [command] := $80;
  239.   Temp := Port[data_high];
  240.   Port [command] := 0;
  241.   Port [data_high] := (Temp AND $df) OR 3;
  242.   GUSDelay;
  243.   Port [command] := 0;
  244.   Port [data_high] := (Temp AND $df) OR 3;
  245.   asm sti end;
  246.   gussetvolume(v,0);
  247. End;
  248.  
  249.  
  250. Procedure GUSPlayVoice( V, Mode : Byte;VBegin, VStart, VEnd : Longint);
  251. Begin
  252.   asm cli end;
  253.   Port [active_voice] := V;
  254.   Port [active_voice] := V;
  255.   port [command] := 0;
  256.   port [data_high] := 2;         {stop voice}
  257.  
  258.   Port [command] := $0A;
  259.   Portw[data_low] := (VBegin SHR 7) AND 8191;
  260.   Port [command] := $0B;
  261.   Portw[data_low] := (VBegin AND 127) SHL 9;
  262.   Port [command] := $02;
  263.   Portw[data_low] := (VStart SHR 7) AND 8191;
  264.   Port [command] := $03;
  265.   Portw[data_low] := (VStart AND 127) SHL 9;
  266.   Port [command] := $04;
  267.   Portw[data_low] := ((VEnd)   SHR 7) AND 8191;
  268.   Port [command] := $05;
  269.   Portw[data_low] := ((VEnd)   AND 127) SHL 9;
  270.  
  271.   Port [command] := $0;
  272.   Port [data_high] := Mode and $fe;
  273.   asm sti end;
  274. end;
  275.  
  276. Procedure GUSPlayAll( V, Mode : Byte;VBegin, VStart, VEnd : Longint;
  277.                       freq,vol : word);
  278. Begin
  279.   asm cli end;
  280.   asm
  281.     mov  dx,active_voice  {Port [active_voice] := V;}
  282.     mov  al,v
  283.     out  dx,al
  284.     mov  cx,command        {port [command] := 0;}
  285.     mov  dx,cx
  286.     mov  al,0
  287.     out  dx,al
  288.     mov  dx,data_high      {port [data_high] := 2;}     {stop voice}
  289.     mov  al,2
  290.     out  dx,al
  291.     mov  dx,cx
  292.     mov  al,9
  293.     out  dx,al             {port [command] := 9;}
  294.     mov  dx,data_low
  295.     mov  ax,vol
  296.     out  dx,ax             {portw[data_low] := vol;}      {set volume}
  297.  
  298.     mov  dx,cx
  299.     mov  al,1
  300.     out  dx,al            {port [command] := 1;}
  301.     mov  dx,data_low
  302.     mov  ax,freq
  303.     out  dx,ax            {portw[data_low] := freq;}
  304.   end;
  305.   Port [command] := $0A;
  306.   Portw[data_low] := (VBegin SHR 7) AND 8191;
  307.   Port [command] := $0B;
  308.   Portw[data_low] := (VBegin AND 127) SHL 9;
  309.   Port [command] := $02;
  310.   Portw[data_low] := (VStart SHR 7) AND 8191;
  311.   Port [command] := $03;
  312.   Portw[data_low] := (VStart AND 127) SHL 9;
  313.   Port [command] := $04;
  314.   Portw[data_low] := ((VEnd)   SHR 7) AND 8191;
  315.   Port [command] := $05;
  316.   Portw[data_low] := ((VEnd)   AND 127) SHL 9;
  317.  
  318.   Port [command] := $0;
  319.   Port [data_high] := Mode and $fe;
  320.   asm sti end;
  321. end;
  322.  
  323. procedure gusrelvoice(v : byte);
  324. var
  325. b : byte;
  326. begin
  327.   port[active_voice] := v;
  328.   port[command] := $80;
  329.   b := port[data_high];
  330.   port[command] := 0;
  331.   port[data_high] := b and $fc;
  332. end;
  333.  
  334. procedure gusrelvoices(n : byte); assembler;
  335. asm
  336.   mov  bl,n
  337. @@1:
  338.   mov  dx,base
  339.   add  dx,102h
  340.   mov  al,bl
  341.   out  dx,al
  342.   inc  dx
  343.   mov  al,80h
  344.   out  dx,al
  345.   add  dx,2
  346.   in   al,dx
  347.   mov  al,0
  348.   sub  dx,2
  349.   out  dx,al
  350.   add  dx,2
  351.   mov  cl,al
  352.   and  cl,0fdh
  353.   mov  al,cl
  354.   out  dx,al
  355.   dec  bl
  356.   jnz  @@1
  357. end;
  358.  
  359. procedure GusSetOfs(v : byte;vbegin : longint);
  360. begin
  361.   asm cli end;
  362.   Port [active_voice] := V;
  363.   Port [active_voice] := V;
  364.   Port [command] := $0A;
  365.   Portw[data_low] := (VBegin SHR 7) AND 8191;
  366.   Port [command] := $0B;
  367.   Portw[data_low] := (VBegin AND 127) SHL 9;
  368.   asm sti end;
  369. end;
  370.  
  371.  
  372. Procedure GUSReset;
  373. var
  374. n : integer;
  375. Begin
  376.   Port[Base] := 3;
  377.   port [base+$103]   := $4C;
  378.   port [Base+$105] := 1;
  379.   GUSDelay;
  380.   port [base+$103] := $4c;
  381.   port [base+$105] := 0;
  382.   gusdelay;
  383.   port [base+$103] := $4c;
  384.   port[base+$105] := 1;
  385.   gusdelay;
  386.   port [base+$103]   := $4C;
  387.   port [Base+$105] := 7;
  388.  
  389.   port [base+$103]   := $0E;
  390.   port [Base+$105] := (13 OR $0C0);
  391.  
  392.   gusdelay;
  393.   port[base] := 1;
  394.   Port[base+_command] := $4C;
  395.   Port[Base+_data_high] := 7;
  396.   n := gus_info[1];
  397.   for n := 1 to 14 do begin
  398.     port[base+_active_voice] := n;
  399.     port[base+_command] := 0;
  400.     port[base+_data_high] := 2;      {stop all voices}
  401.     port[base+_command] := $d;
  402.     port[base+_data_high] := 2;
  403.     port[base+_command] := $a;
  404.     portw[base+_data_low] := 0;
  405.     port[base+_command] := $b;
  406.     portw[base+_data_low] := 0;
  407.     port[base+_command] := 9;
  408.     portw[base+_data_low] := 0;
  409.   end;
  410. End;
  411.  
  412. {$s-}
  413.  
  414. procedure gusdeinit;
  415. var
  416. n : word;
  417. begin
  418.   for n := 1 to 14 do gusstopvoice(n);
  419. end;
  420.